#include "imgProc.h"

void erodeImage(IplImage* image) {
	int x, y;
	//IlpImage* erodedImage;
	for (y = 0; y < HEIGHT; y++) {
		for (x = 0; x < WIDTH; x++) {
			int temp = (y * WIDTH + x) * 3;

			if (y != 0 && y != HEIGHT && x != 0 && x != WIDTH) {
			} else {
				image->imageData[temp + 2] = 0;
				image->imageData[temp + 1] = 0;
				image->imageData[temp] = 0;
				continue;
			}

			if (image->imageData[temp] == 255) {
				int count = 0;

				count += image->imageData[((y - 1) * WIDTH + (x - 1)) * 3];
				count += image->imageData[((y - 1) * WIDTH + (x)) * 3];
				count += image->imageData[((y) * WIDTH + (x - 1)) * 3];
				count += image->imageData[((y + 1) * WIDTH + (x + 1)) * 3];
				count += image->imageData[((y + 1) * WIDTH + (x)) * 3];
				count += image->imageData[((y) * WIDTH + (x + 1)) * 3];
				count += image->imageData[((y - 1) * WIDTH + (x + 1)) * 3];
				count += image->imageData[((y + 1) * WIDTH + (x - 1)) * 3];

				if (count > 255 * 2) {
					image->imageData[temp + 2] = 255;
					image->imageData[temp + 1] = 255;
					image->imageData[temp] = 255;
				} else {
					image->imageData[temp + 2] = 0;
					image->imageData[temp + 1] = 0;
					image->imageData[temp] = 0;
				}
			}
		}
	}
	//erodedImage = image;
}

void findCentre(IplImage* image, coordinate_t &point, areaCoordinate_t &interestedArea) {
	int y, x;
	int avg = 0;
	int sum = 0;
	int x1, x2, y1, y2;

	x1 = interestedArea.point1.x;
	y1 = interestedArea.point1.y;
	x2 = interestedArea.point2.x;
	y2 = interestedArea.point2.y;

	for (y = y1; y < y2; y++) {
		for (x = x1; x < x2; x++) {
			int temp = (y * WIDTH + x) * 3;
			if (image->imageData[temp] == 255) {
				avg++;
			}
		}
	}
	avg /= 2;

	for (y = y1; y < y2; y++) {
		for (x = x1; x < x2; x++) {
			int temp = (y * WIDTH + x) * 3;
			if (image->imageData[temp] == 255) {
				sum++;
			}
		}

		if (sum >= avg) {
			point.y = y;
			break;
		}
	}

	//printf("cccccc  %d\n", (x2-x1)*(y2-y1));
	//printf("avg sum %d %d\n", avg, sum);
	sum = 0;

	for (x = x1; x < x2; x++) {
		for (y = y1; y < y2; y++) {
			int temp = (y * WIDTH + x) * 3;
			if (image->imageData[temp] == 255) {
				sum++;
			}
		}

		if (sum >= avg) {
			point.x = x;
			break;
		}
	}
}


void input(unsigned char *input, unsigned char *output, int channel, int height,
		int width) {
	int R, G, B, i, j;
	//printf("%d %d %d %d\n", input, channel,  height, width);
	for (i = 0; i < HEIGHT; i++) {
		for (j = 0; j < WIDTH; j++) {
			int temp = (i * WIDTH + j) * 3;
			R = input[temp + 2];
			G = input[temp + 1];
			B = input[temp + 0];

			if (R > 95 && G > 40 && B > 20 &&
			MAX(R, MAX(G,B)) - MIN(R, MIN(G,B)) > 15 &&
			ABS(R,G) > 15 && R > G && R > B) {
				output[temp + 2] = 255;
				output[temp + 1] = 255;
				output[temp] = 255;
			} else {
				output[temp + 2] = 0;
				output[temp + 1] = 0;
				output[temp] = 0;
			}
		}
	}

	//cvReleaseImage(&output);
	//cvReleaseImage(&input);
	return;
}

void crossline(BYTE* img, int x, int y, int thick) {
	int i, j;

	for (i = 0; i < HEIGHT; i++) {
		for (j = 0; j < WIDTH * 3; j++) {
			if ((j >= x - thick / 2 && j <= x + thick / 2)
					|| (i > y - thick / 2 && i < y + thick / 2)) { // X축에 등호를 사용하여 두께 보정
				img[i * WIDTH * 3 + j * 3 + 0] = 255;
				img[i * WIDTH * 3 + j * 3 + 1] = 0;
				img[i * WIDTH * 3 + j * 3 + 2] = 0;
			}
		}
	}
}

void circle(BYTE* img, int x, int y, int rad, int thick, int r, int g, int b) {
	int i, j;

	for (i = 0; i < HEIGHT; i++) {
		for (j = 0; j < WIDTH * 3; j++) {
			if ((i - y) * (i - y) + (j - x) * (j - x)
					>= (rad - thick) * (rad - thick)
					&& (i - y) * (i - y) + (j - x) * (j - x)
							< (rad + thick) * (rad + thick)) {
				img[i * WIDTH * 3 + j * 3 + 0] = b;
				img[i * WIDTH * 3 + j * 3 + 1] = g;
				img[i * WIDTH * 3 + j * 3 + 2] = r;
			}
		}
	}
}

/*
void square(BYTE* img, int x1, int x2, int y1, int y2, int thick) {
	int rwsize2 = WIDTHBYTES(24 * WIDTH);
	int i, j;

	for (i = 0; i < HEIGHT; i++) {
		for (j = 0; j < WIDTH * 3; j++) {
			if ((j >= x1 - thick / 2 && j <= x1 + thick / 2)
					&& (i >= y1 && i <= y2)
					|| (j >= x2 - thick / 2 && j <= x2 + thick / 2)
							&& (i >= y1 && i <= y2)
					|| (i >= y1 - thick / 2 && i <= y1 + thick / 2)
							&& (j >= x1 - 1 && j <= x2 + 1)
					|| (i >= y2 - thick / 2 && i <= y2 + thick / 2)
							&& (j >= x1 - 1 && j <= x2 + 1)) { // x범위 +-1 >> 사각형 모서리 처리
				img[i * rwsize2 + j * 3 + 0] = 0;
				img[i * rwsize2 + j * 3 + 1] = 0;
				img[i * rwsize2 + j * 3 + 2] = 255;
			}
		}
	}
}

void cross(BYTE* img, int x, int y, int thick, int length, int r, int g,
		int b) {
	int rwsize2 = WIDTHBYTES(24 * WIDTH);
	int i, j;

	for (i = 0; i < HEIGHT; i++) {
		for (j = 0; j < WIDTH * 3; j++) {
			if (((j >= x - thick / 2 && j <= x + thick / 2)
					&& (i >= y - length / 2 && i <= y + length / 2))
					|| ((j >= x - length / 2 && j <= x + length / 2)
							&& (i > y - thick / 2 && i < y + thick / 2))) { // X축에 등호를 사용하여 두께 보정
				img[i * rwsize2 + j * 3 + 0] = b;
				img[i * rwsize2 + j * 3 + 1] = g;
				img[i * rwsize2 + j * 3 + 2] = r;
			}
		}
	}
}
*/
void findcircle(BYTE* img, BYTE* biimg, int x, int y, int rad, int thick, int r,
		int g, int b) {
	int flag = 0;
	int i, j;

	for (i = 0; i < HEIGHT; i++) {
		int temp = i * WIDTH;
		for (j = 0; j < WIDTH * 3; j++) {
			if ((i - y) * (i - y) + (j - x) * (j - x)
					>= (rad - thick) * (rad - thick)
					&& (i - y) * (i - y) + (j - x) * (j - x)
							< (rad + thick) * (rad + thick)) {
				if (img[(temp + j) * 3] == 255) {
					img[(temp + j) * 3 + 0] = b;
					img[(temp + j) * 3 + 1] = g;
					img[(temp + j) * 3 + 2] = r;
				}
			}
		}
	}
}
/*
 void findmass(BYTE* img, BYTE*oriimg, int *radious){

 int SumX = 1, SumY = 1, count = 1;

 int initX = HEIGHT, initY = WIDTH;
 int lastX = 1, lastY = 1;
 int i, j, temp;

 //	printf("log:findmass\n");
 for (i = 5; i < HEIGHT-5; i++){			//가로 검색 및 무게중심
 for (j = 5; j < WIDTH-5; j++){
 temp =i*WIDTH;
 if (img[(temp+ j)*3] == 255){
 SumX += j;
 SumY += i;
 count++;
 if (i < initY)
 initY = i;
 lastY = i;	//y2(마지막 overwriten y value)
 }
 }
 }


 for (j = 5; j < WIDTH-5; j++){				//세로 검색
 for (i = 5; i < HEIGHT-5; i++){
 temp = i*WIDTH;
 if (img[(temp+ j)*3] == 255){
 if (j < initX)
 initX = j;
 lastX = j; //x2(마지막 overwriten x value)
 }
 }
 }
 if(SumX != 0 && SumY!= 0 && count != 0){
 //printf("%d, %d\n",SumX/count, SumY/count);
 //printf("%d, %d, %d, %d\n",initX, lastX, initY, lastY);
 if(((lastX -initX)/(lastY-initY)) < 3 && ((lastX -initX)/(lastY-initY)) > 1/3)
 {
 printf("maybe it's hand");
 // *radious = max((lastX - initX)/2, (lastY - initY)/2)*4/6;
 //printf("ra : %d\n", *radious);
 ///findcircle(oriimg, img, SumX / count, SumY / count, *radious, 4, 0, 0, 255);
 cross(oriimg, SumX / count, SumY / count, 2, 50, 0, 255, 0);
 square(oriimg, initX, lastX, initY, lastY, 2);
 printf("moving : %d\n",notMoving( SumX / count, SumY / count, countMovingX, countMovingY ));
 }
 }
 }
 */

/*
void rgb2hsi(unsigned char *originalImg, unsigned short *hImg,
		unsigned char *sImg, unsigned char *iImg) {
	int i, j;
	double minc, angle;

	int red, green, blue;
	float fR, fG, fB;

	for (i = 0; i < HEIGHT; i++) {
		for (j = 0; j < WIDTH; j++) {
			red = originalImg[(i * WIDTH + j) * 3 + 2];
			green = originalImg[(i * WIDTH + j) * 3 + 1];
			blue = originalImg[(i * WIDTH + j) * 3 + 0];

			//정규화된 RGB로 변환
			if (red == 0 && green == 0 && blue == 0) {
				fR = 0.0f;
				fG = 0.0f;
				fB = 0.0f;
			} else {
				fR = (float) red / (red + green + blue);
				fG = (float) green / (red + green + blue);
				fB = (float) blue / (red + green + blue);
			}

			minc = MIN(fR, fG);
			minc = MIN(minc, fB);

			iImg[i * WIDTH + j] = (unsigned char) ((red + green + blue) / 3);

			if ((fR == fG) && (fG == fB)) {		// Gray Scale
				hImg[i * WIDTH + j] = 0;
				sImg[i * WIDTH + j] = 0;
				continue;
			} else {
				//sImg[i * width + j] = (BYTE)(255.0 - 3.0 * minc *255 / (red + green + blue));
				sImg[i * WIDTH + j] = (BYTE) (1.0f - 3.0f * minc * 255.0f);	//fR+fG+fB = 1.0이니까

				//angle = (((red - green) + (red - blue)) >> 1) / (double)(sqrt((double)((red - green) * (red - green) + (red - blue) * (green - blue))));
				angle = (fR - 0.5f * fG - 0.5f * fB)
						/ (float) sqrt(
								(fR - fG) * (fR - fG) + (fR - fB) * (fG - fB));
				hImg[i * WIDTH + j] = (WORD) (acos(angle) * 57.29577951);
			}

			if (fB > fG)
				hImg[i * WIDTH + j] = (WORD) (360 - hImg[i * WIDTH + j]);

			//sImg[i * width + j] *= 255.0f;
		}
	}
	return;
}
*/

/*
void compareBGwithQ(queue_t* set, BYTE* input, BYTE* output) {
	int sum[WIDTH * HEIGHT];
	pthread_t tid[3];
	int length = (int) (set->front->data[0]);
	printf("compared BG start, length : %d\n", length);

	node_t* thisNode = set->front->next;

	for (int i = 0; i < length; i++) {
		for (int j = 0; j < WIDTH * HEIGHT; j++) { //현재큐의 데이터받아옴
			sum[j] += thisNode->data[j];
		}
		thisNode = thisNode->next; //큐 순번 옮김
	}
	if (length > 0) {
		for (int j = 0; j < WIDTH * HEIGHT; j++) {
			sum[j] = sum[j] / length; //평균 구함
			if ((input[j] - sum[j]) > 50 || (sum[j] - input[j]) > 50) {
				output[j] = 0; //차이값크면 0
			} else {
				output[j] = 255;
			}
		}
	}

	enqueue(set, input); // 새로들어온거 넣기
	if (length > 3) {
		dequeue(set);
	}

}
*/